package com.lxmes.hr.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.List;
import java.util.stream.Collectors;

import com.lxmes.common.exception.ServiceException;
import com.lxmes.common.utils.DateUtils;
import com.lxmes.common.utils.StringUtils;
import com.lxmes.common.utils.bean.BeanValidators;
import com.lxmes.hr.domain.*;
import com.lxmes.hr.mapper.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.lxmes.hr.service.INcAttendSummaryService;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Validator;

/**
 * 考勤汇总Service业务层处理
 *
 * @author zhangzhiyu
 * @date 2022-11-25
 */
@Service
public class NcAttendSummaryServiceImpl implements INcAttendSummaryService
{
    @Autowired
    private NcAttendSummaryMapper ncAttendSummaryMapper;

    @Autowired
    private NcAttendRgMapper ncAttendRgMapper;

    @Autowired
    private NcAttendDetailMapper ncAttendDetailMapper;

    @Autowired
    private NcAttendBaseMapper ncAttendBaseMapper;

    @Autowired
    private NcSchedulingRulesMapper ncSchedulingRulesMapper;


    @Autowired
    private NcAbnormalAttendMapper ncAbnormalAttendMapper;



    @Autowired
    protected Validator validator;

    /**
     * 查询考勤汇总
     *
     * @param id 考勤汇总主键
     * @return 考勤汇总
     */
    @Override
    public NcAttendSummary selectNcAttendSummaryById(Long id)
    {
        return ncAttendSummaryMapper.selectNcAttendSummaryById(id);
    }

    /**
     * 查询考勤汇总列表
     *
     * @param ncAttendSummary 考勤汇总
     * @return 考勤汇总
     */
    @Override
    public List<NcAttendSummary> selectNcAttendSummaryList(NcAttendSummary ncAttendSummary)
    {
        return ncAttendSummaryMapper.selectNcAttendSummaryList(ncAttendSummary);
    }

    /**
     * 新增考勤汇总
     *
     * @param ncAttendSummary 考勤汇总
     * @return 结果
     */
    @Override
    public int insertNcAttendSummary(NcAttendSummary ncAttendSummary)
    {
        return ncAttendSummaryMapper.insertNcAttendSummary(ncAttendSummary);
    }

    /**
     * 修改考勤汇总
     *
     * @param ncAttendSummary 考勤汇总
     * @return 结果
     */
    @Override
    public int updateNcAttendSummary(NcAttendSummary ncAttendSummary)
    {
        return ncAttendSummaryMapper.updateNcAttendSummary(ncAttendSummary);
    }

    /**
     * 批量删除考勤汇总
     *
     * @param ids 需要删除的考勤汇总主键
     * @return 结果
     */
    @Override
    public int deleteNcAttendSummaryByIds(Long[] ids)
    {
        return ncAttendSummaryMapper.deleteNcAttendSummaryByIds(ids);
    }

    /**
     * 删除考勤汇总信息
     *
     * @param id 考勤汇总主键
     * @return 结果
     */
    @Override
    public int deleteNcAttendSummaryById(Long id)
    {
        return ncAttendSummaryMapper.deleteNcAttendSummaryById(id);
    }

    @Override
    public String imporIteminfo(List<NcAttendSummary> userList, boolean updateSupport, String operName) {
        if (StringUtils.isNull(userList) || userList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        for (NcAttendSummary org : userList)
        {
            try
            {
                BeanValidators.validateWithException(validator, org);
                org.setCreateBy(operName);
                org.setUpdateBy(operName);
                this.insertNcAttendSummary(org);
                successNum++;
                successMsg.append("<br/>" + successNum + "、员工姓名 " + org.getPName() + " 导入成功");
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + org.getPName() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

    @Override
    @Transactional
    //默认统计上个月
    public int summaryAttend(String type) {
                    String month = DateUtils.getLastMonth();
//        String month = DateUtils.getMonth();
        NcAttendSummary ncAttendSummary = new NcAttendSummary();
        ncAttendSummary.setKqDate(month);
        ncAttendSummary.setDataSource(type);
        ncAttendSummaryMapper.deleteNcAttendSummaryByMonth(ncAttendSummary);


        NcAttendBase ncAttendBase = new NcAttendBase();
        ncAttendBase.setYearN(month.replace("-",""));
        List<NcAttendBase> ncAttendBases = ncAttendBaseMapper.selectNcAttendBaseList(ncAttendBase);

        String y = month.split("-")[0];
        NcSchedulingRules rules = new NcSchedulingRules();
        rules.setYear(y);
        List<NcSchedulingRules> ruleInfos = ncSchedulingRulesMapper.selectRulesListCondition(rules);
        if(ruleInfos.size()==0){
            throw new RuntimeException("请先设置人员信息" + month.split("-")[0] + "年的排班规则。");
        }

        NcAttendSummary summary = new NcAttendSummary();
        if("rg".equals(type)){
            NcAttendRg rg = new NcAttendRg();
            rg.setKqDate(month);
            List<NcAttendRg> ncAttendRgs = ncAttendRgMapper.selectNcAttendRgGroupBy(rg);
            for(NcAttendRg attendRg : ncAttendRgs){
                summary.setFactoryCode(attendRg.getGcCode());
                summary.setFactoryName(attendRg.getGcName());
                summary.setPName(attendRg.getEmployeeName());
                summary.setJobNo(attendRg.getJobNumber());
                summary.setDepartment(attendRg.getDepartment());
                summary.setBranch(attendRg.getBranch());
                summary.setEntryDate(attendRg.getRzDate());
                summary.setPGroup(attendRg.getZb());
                summary.setJobs(attendRg.getJobs());
                summary.setActualDayNum(attendRg.getActDays());
                summary.setSdTime(attendRg.getSdTime());
                summary.setJjrTime(attendRg.getJjrTime());
                summary.setJbTime(attendRg.getJbTime());
                summary.setRestDay(attendRg.getRestDay());
                summary.setLeaveDay(attendRg.getLeaveDay());
                summary.setLunDay(attendRg.getLunDay());
                summary.setXlzqqDay(attendRg.getXlzqqDay());
                summary.setKgDayNum(attendRg.getKgDayNum());
                summary.setYcqDay(attendRg.getYcqDay());
                summary.setDataSource("rg");
                summary.setKqDate(month);
                summary.setAttendCalBase(ncAttendBases.get(0).getGzr().doubleValue());
                insertNcAttendSummary(summary);
            }
        }else {
            NcAttendDetail ncAttendDetail = new NcAttendDetail();
            ncAttendDetail.setNyDate(month);
            List<NcAttendDetail> ncAttendDetails = ncAttendDetailMapper.selectNcAttendDetailList(ncAttendDetail);
            for(NcAttendDetail attendDetail : ncAttendDetails){
                summary.setFactoryCode(attendDetail.getGcCode());
                summary.setFactoryName(attendDetail.getGcName());
                summary.setPName(attendDetail.getEmployeeName());
                summary.setJobNo(attendDetail.getJobNumber());
                summary.setDepartment(attendDetail.getDepartment());
                summary.setBranch(attendDetail.getBranch());
                summary.setEntryDate(attendDetail.getEntryDate());
                summary.setPGroup(attendDetail.getZb());
                summary.setJobs(attendDetail.getJobs());
                BigDecimal zc = jsDayNum("全天正常", attendDetail);
                BigDecimal zmjb = jsDayNum("周末加班", attendDetail);
                BigDecimal jjrjb = jsDayNum("节假日加班", attendDetail);
                summary.setActualDayNum(zc.add(zmjb).add(jjrjb));
                List<NcSchedulingRules> ruleInfo = ruleInfos.parallelStream().filter(rule -> attendDetail.getJobNumber().equals(rule.getJobNo())).collect(Collectors.toList());
                if(ruleInfo.size()==0){
                    throw new RuntimeException("请先设置" + attendDetail.getEmployeeName() + "的" + y + "年的排班规则。");
                }
                double wl = ruleInfo.get(0).getWorkLength();
                summary.setSdTime(summary.getActualDayNum().multiply(new BigDecimal(wl)));
                summary.setJjrTime(new BigDecimal(attendDetail.getJbJjr()*wl));
                summary.setZmTime(new BigDecimal(attendDetail.getJbWeekend()*wl));
                double h = attendDetail.getJbMin()/60;
                BigDecimal hour = new BigDecimal(h).setScale(2, RoundingMode.HALF_UP);
                summary.setJbTime(hour);
                BigDecimal zmxb = jsDayNum("周末休班", attendDetail);
                BigDecimal jjrxb = jsDayNum("节假日休班", attendDetail);
                summary.setRestDay(zmxb.add(jjrxb));

//                NcAbnormalAttend ncAbnormalAttend = new NcAbnormalAttend();
//                ncAbnormalAttend.setWorkNum(attendDetail.getJobNumber());
//                List<NcAbnormalAttend> ncAbnormalAttends = ncAbnormalAttendMapper.selectNcAbnormalAttendList(ncAbnormalAttend);

//                summary.setLeaveDay();
//                summary.setLunDay(attendRg.getLunDay());
//                summary.setXlzqqDay(attendRg.getXlzqqDay());
//                summary.setKgDayNum(attendRg.getKgDayNum());
                summary.setYcqDay(new BigDecimal(ncAttendBases.get(0).getYcqts()));
                summary.setDataSource("system");
                summary.setKqDate(month);
                summary.setAttendCalBase(ncAttendBases.get(0).getGzr().doubleValue());
                insertNcAttendSummary(summary);
            }
        }

        return 1;
    }

    public BigDecimal jsDayNum(String type,NcAttendDetail attendDetail){
        int a = 0 ;
        if(type.equals(attendDetail.getDay1())){
            a++;
        }
        if(type.equals(attendDetail.getDay2())){
            a++;
        }
        if(type.equals(attendDetail.getDay3())){
            a++;
        }
        if(type.equals(attendDetail.getDay4())){
            a++;
        }
        if(type.equals(attendDetail.getDay5())){
            a++;
        }
        if(type.equals(attendDetail.getDay6())){
            a++;
        }
        if(type.equals(attendDetail.getDay7())){
            a++;
        }
        if(type.equals(attendDetail.getDay8())){
            a++;
        }
        if(type.equals(attendDetail.getDay9())){
            a++;
        }
        if(type.equals(attendDetail.getDay10())){
            a++;
        }
        if(type.equals(attendDetail.getDay11())){
            a++;
        }
        if(type.equals(attendDetail.getDay12())){
            a++;
        }
        if(type.equals(attendDetail.getDay13())){
            a++;
        }
        if(type.equals(attendDetail.getDay14())){
            a++;
        }
        if(type.equals(attendDetail.getDay15())){
            a++;
        }
        if(type.equals(attendDetail.getDay16())){
            a++;
        }
        if(type.equals(attendDetail.getDay17())){
            a++;
        }
        if(type.equals(attendDetail.getDay18())){
            a++;
        }
        if(type.equals(attendDetail.getDay19())){
            a++;
        }
        if(type.equals(attendDetail.getDay20())){
            a++;
        }
        if(type.equals(attendDetail.getDay21())){
            a++;
        }
        if(type.equals(attendDetail.getDay22())){
            a++;
        }
        if(type.equals(attendDetail.getDay23())){
            a++;
        }
        if(type.equals(attendDetail.getDay24())){
            a++;
        }
        if(type.equals(attendDetail.getDay25())){
            a++;
        }
        if(type.equals(attendDetail.getDay26())){
            a++;
        }
        if(type.equals(attendDetail.getDay27())){
            a++;
        }
        if(type.equals(attendDetail.getDay28())){
            a++;
        }
        if(attendDetail.getDay29()!=null){
            if(type.equals(attendDetail.getDay29())){
                a++;
            }
        }

        if(attendDetail.getDay30()!=null){
            if(type.equals(attendDetail.getDay30())){
                a++;
            }
        }

        if(attendDetail.getDay31()!=null){
            if(type.equals(attendDetail.getDay31())){
                a++;
            }
        }

        return new BigDecimal(a);
    }

}
